package com.molichuxing.services.business.service.impl;

import com.molichuxing.framework.dto.Paged;
import com.molichuxing.framework.dto.TabDto;
import com.molichuxing.framework.exception.BizException;
import com.molichuxing.framework.utils.DateUtil;
import com.molichuxing.framework.utils.ObjectCastUtil;
import com.molichuxing.services.business.convertor.Convert;
import com.molichuxing.services.business.dto.request.create.OrderEnterpriseCreateBizDto;
import com.molichuxing.services.business.dto.request.create.OrderEnterpriseLeaseConfirmBizDto;
import com.molichuxing.services.business.dto.request.modify.EnterprisePayModifyBizDto;
import com.molichuxing.services.business.dto.request.modify.EnterpriseRenewCarLeaseModifyBizDto;
import com.molichuxing.services.business.dto.request.modify.EnterpriseRenewLeaseModifyBizDto;
import com.molichuxing.services.business.dto.response.*;
import com.molichuxing.services.business.service.EnterpriseScheduleBizService;
import com.molichuxing.services.business.service.OrderEnterpriseBizService;
import com.molichuxing.services.exception.OrderExceptionCodeEnum;
import com.molichuxing.services.infrastructure.dto.request.create.EnterpriseCarCreateDto;
import com.molichuxing.services.infrastructure.dto.request.create.EnterpriseScheduleCarCreateDto;
import com.molichuxing.services.infrastructure.dto.request.create.EnterpriseScheduleCreateDto;
import com.molichuxing.services.infrastructure.dto.request.create.OrderEnterpriseCreateDto;
import com.molichuxing.services.infrastructure.dto.request.modify.EnterpriseCarModifyDto;
import com.molichuxing.services.infrastructure.dto.response.*;
import com.molichuxing.services.infrastructure.service.*;
import com.molichuxing.services.property.*;
import com.molichuxing.services.utils.OrderUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.toList;

/**
 * 企业订单biz service
 *
 * @Author zoumingyu
 * @Date 2020年06月08日
 */
@Service("orderEnterpriseBizService")
public class OrderEnterpriseBizServiceImpl implements OrderEnterpriseBizService {
    private static final Logger logger = LoggerFactory.getLogger(OrderEnterpriseBizServiceImpl.class);

    @Resource
    private EnterpriseScheduleBizService enterpriseScheduleBizService;

    @Resource
    private OrderEnterpriseService orderEnterpriseService;

    @Resource
    private EnterpriseCarService enterpriseCarService;

    @Resource
    private EnterpriseStateFlowService enterpriseStateFlowService;

    @Resource
    private EnterpriseScheduleService enterpriseScheduleService;

    @Resource
    private EnterpriseScheduleCarService enterpriseScheduleCarService;

    @Resource
    private EnterpriseCarTransferService enterpriseCarTransferService;

    @Resource
    private EnterpriseCarHandoverService enterpriseCarHandoverService;

    /**
     * 新增企业订单
     *
     * @param createBizDto 新增信息
     * @return Long 订单号
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public Long create(OrderEnterpriseCreateBizDto createBizDto) {
        LocalDate leaseInception = null,
                leaseExpire = null;
        // 判断是否是续订单
        if (createBizDto.getPrentOrderCode() != null && createBizDto.getPrentOrderCode() > 0) {
            // 是续订单，查询主订单信息
            OrderEnterpriseDto parentOrder = orderEnterpriseService.getEnterprise(createBizDto.getPrentOrderCode());
            if (parentOrder == null) {
                logger.error("[create]企业订单续订失败，主订单不存在");
                throw new BizException(OrderExceptionCodeEnum.NOT_EXIST.getCode(), "企业订单续订失败");
            }
            // 查询主订单还款情况
            List<EnterpriseScheduleDto> parentNoPaySchedules = enterpriseScheduleService
                    .getSchedule(createBizDto.getPrentOrderCode(), EnterpriseScheduleStateEnum.NO);
            if (parentNoPaySchedules != null && !parentNoPaySchedules.isEmpty()) {
                logger.error("[create]订单({})存在未还款的还款计划，请还款后再进行续租", createBizDto.getPrentOrderCode());
                throw new BizException(OrderExceptionCodeEnum.ERROR.getCode(),
                        "订单存在未还款的还款计划，请还款后再进行续租");
            }

            // 修改主订单
            if (!orderEnterpriseService.modifyHaveSuborder(parentOrder.getOrderCode())) {
                logger.error("[create]企业订单续订修改主订单失败");
                throw new BizException(OrderExceptionCodeEnum.ERROR.getCode(), "企业订单续订失败");
            }
            // 续订单起租日和截止日
            leaseInception = parentOrder.getLeaseExpire().plusDays(1);
            leaseExpire = leaseInception.plusMonths(createBizDto.getTenancy());


            // TODO 验证车辆？
        }
        // 订单号
        Long orderCode = OrderUtil.getOrderCode();
        // 企业订单车辆信息
        List<OrderEnterpriseCreateBizDto.EnterpriseCarCreateBizDto> cars = createBizDto.getCars();
        // 总租金,总保证金
        BigDecimal rental = BigDecimal.ZERO, deposit = BigDecimal.ZERO;
        List<EnterpriseCarCreateDto> carCreateDtoList = new ArrayList<>(cars.size());
        // 循环
        for (OrderEnterpriseCreateBizDto.EnterpriseCarCreateBizDto carCreateBizDto : cars) {
            // 每期租金（每月租金 * 还款周期）
            BigDecimal periodsRental = carCreateBizDto.getMonthlyRental().multiply(new BigDecimal(createBizDto.getRepaymentPeriod()));
            // 车辆总租金（每辆车的租金）（每月租金 * 租期（月））
            BigDecimal carRental = carCreateBizDto.getMonthlyRental().multiply(new BigDecimal(createBizDto.getTenancy()));
            // 累加租金和保证金
            rental = rental.add(carRental);
            deposit = deposit.add(carCreateBizDto.getDeposit());

            EnterpriseCarCreateDto carCreateDto = Convert.toEnterpriseCarCreateDto(carCreateBizDto);
            carCreateDto.setOrderCode(orderCode);
            carCreateDto.setPeriodsRental(periodsRental);
            carCreateDtoList.add(carCreateDto);
        }
        // 新增订单车辆
        if (!enterpriseCarService.createBatch(carCreateDtoList)) {
            logger.error("[create]新增企业订单车辆信息失败");
            throw new BizException(OrderExceptionCodeEnum.ERROR.getCode(), "新增企业订单车辆信息失败");
        }
        // 新增订单信息
        OrderEnterpriseCreateDto createDto = Convert.toOrderEnterpriseCreateDto(createBizDto);
        createDto.setOrderCode(orderCode);
        createDto.setRental(rental);
        createDto.setDeposit(deposit);
        createDto.setLeaseInception(leaseInception);
        createDto.setLeaseExpire(leaseExpire);
        if (orderEnterpriseService.create(createDto) <= 0) {
            logger.error("[create]新增企业订单失败");
            throw new BizException(OrderExceptionCodeEnum.ERROR.getCode(), "新增企业订单失败");
        }
        // 新增订单流转信息
        enterpriseStateFlowService.create(Convert.toEnterpriseStateFlowCreateDto(orderCode, createBizDto));

        return orderCode;
    }

    /**
     * 支付完成修改企业订单信息
     *
     * @param modifyBizDto 修改信息
     * @return boolean
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public boolean modifyPay(EnterprisePayModifyBizDto modifyBizDto) {
        // 判断是否是首付
        if (modifyBizDto.getScheduleId() == null || modifyBizDto.getScheduleId() == 0) {
            // 首付
            return modifyDownPay(modifyBizDto);
        } else {
            // 还款
            return modifyRepay(modifyBizDto);
        }
    }

    /**
     * 还款修改
     *
     * @param modifyBizDto 修改信息
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public boolean modifyRepay(EnterprisePayModifyBizDto modifyBizDto) {
        // 查询订单信息
        OrderEnterpriseDto order = orderEnterpriseService.getEnterprise(modifyBizDto.getOrderCode());
        if (order == null) {
            logger.error("[modifyRepay]还款完成修改企业订单排期失败，订单({})不存在", modifyBizDto.getOrderCode());
            return false;
        } else if (EnterpriseStateEnum.DELIVERY.getValue() != order.getState()) {
            logger.error("[modifyRepay]还款完成修改企业订单排期失败，订单({})" +
                    "状态({})不是已交车状态", modifyBizDto.getOrderCode(), order.getState());
            return false;
        }
        // 根据排期id查询排期信息
        EnterpriseScheduleDto schedule = enterpriseScheduleService.getScheduleById(modifyBizDto.getScheduleId());
        if (schedule == null) {
            logger.error("[modifyRepay]还款完成修改企业订单排期失败，订单({})" +
                    "排期({})不存在", modifyBizDto.getOrderCode(), modifyBizDto.getScheduleId());
            return false;
        } else if (schedule.getState() != EnterpriseScheduleStateEnum.NO.getValue()) {
            logger.error("[modifyRepay]还款完成修改企业订单排期失败，订单({})" +
                    "排期({})不不是未还款", modifyBizDto.getOrderCode(), modifyBizDto.getScheduleId());
            return false;
        }
        // 查询上一期还款全款
        EnterpriseScheduleDto prevSchedule = enterpriseScheduleService.getSchedule(modifyBizDto.getOrderCode(), schedule.getPeriods() - 1);
        if (prevSchedule == null) {
            logger.error("[modifyRepay]还款完成修改企业订单排期失败，订单({})" +
                    "排期期数({})不存在", modifyBizDto.getOrderCode(), schedule.getPeriods() - 1);
            return false;
        } else if (prevSchedule.getState() != EnterpriseScheduleStateEnum.ALREADY.getValue()) {
            logger.error("[modifyRepay]还款完成修改企业订单排期失败，订单({})" +
                    "排期期数({})不不是已还款，不能跳期还款", modifyBizDto.getOrderCode(), schedule.getPeriods() - 1);
            return false;
        }

        // 修改订单排期状态
        if (!enterpriseScheduleService.modifyRepay(modifyBizDto.getScheduleId(), modifyBizDto.getArrivalAmount(),
                modifyBizDto.getPayTime())) {
            logger.error("[modifyRepay]还款完成修改企业订单({})排期({})失败", modifyBizDto.getOrderCode(), modifyBizDto.getScheduleId());
            throw new BizException(OrderExceptionCodeEnum.ERROR.getCode(), "修改排期状态失败");
        }
        // 修改订单车辆排期状态
        if (!enterpriseScheduleCarService.modifyRepay(modifyBizDto.getScheduleId())) {
            logger.error("[modifyRepay]还款完成修改企业订单({})车辆排期({})失败", modifyBizDto.getOrderCode(), modifyBizDto.getScheduleId());
            throw new BizException(OrderExceptionCodeEnum.ERROR.getCode(), "修改车辆排期状态失败");
        }

        return true;
    }

    /**
     * 首付修改
     *
     * @param modifyBizDto 修改信息
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public boolean modifyDownPay(EnterprisePayModifyBizDto modifyBizDto) {
        // 查询订单信息
        OrderEnterpriseDto order = orderEnterpriseService.getEnterprise(modifyBizDto.getOrderCode());
        if (order == null) {
            logger.error("[modifyDownPay]支付完成修改企业订单失败，订单(" + modifyBizDto.getOrderCode() + ")不存在");
            return false;
        } else if (EnterpriseStateEnum.UNPAID.getValue() != order.getState()) {
            logger.error("[modifyDownPay]支付完成修改企业订单失败，订单(" + modifyBizDto.getOrderCode() + ")" +
                    "状态(" + order.getState() + ")不是待支付状态");
            return false;
        }

        // 新增首付排期信息
        if (!enterpriseScheduleBizService.createPay(Convert.toEnterpriseScheduleCreateBizDto(order, modifyBizDto))) {
            logger.error("[modifyPay]支付完成新增企业订单(" + modifyBizDto.getOrderCode() + ")排期失败");
            throw new BizException(OrderExceptionCodeEnum.ERROR.getCode(), "订单新增排期失败");
        }

        EnterpriseStateEnum newState = null;
        EnterpriseCarStateEnum carNewState = null;
        // 判断该订单是否为续订单
        if (order.getPrentOrderCode() != null && order.getPrentOrderCode() > 0L) {
            // 续订单，直接变为待起租
            newState = EnterpriseStateEnum.UNHIRE;
            carNewState = EnterpriseCarStateEnum.UNHIRE;
        } else {
            newState = EnterpriseStateEnum.UNDELIVERY;
            carNewState = EnterpriseCarStateEnum.UNDELIVERY;
        }
        // 修改订单状态
        if (!orderEnterpriseService.modifyState(modifyBizDto.getOrderCode(), EnterpriseStateEnum.UNPAID,
                newState)) {
            logger.error("[modifyPay]支付完成修改企业订单(" + modifyBizDto.getOrderCode() + ")状态失败");
            throw new BizException(OrderExceptionCodeEnum.ERROR.getCode(), "修改订单状态失败");
        }
        // 修改订单车辆状态
        if (!enterpriseCarService.modifyState(modifyBizDto.getOrderCode(), EnterpriseCarStateEnum.UNPAID, carNewState)) {
            logger.error("[modifyPay]支付完成修改企业订单(" + modifyBizDto.getOrderCode() + ")车辆状态失败");
            throw new BizException(OrderExceptionCodeEnum.ERROR.getCode(), "订单修改车辆状态失败");
        }

        // 新增订单流转信息
        enterpriseStateFlowService.create(Convert.toEnterpriseStateFlowCreateDto(modifyBizDto, newState));

        return true;
    }

    /**
     * 分页查询企业订单列表
     *
     * @param params
     * @param pageNum  页数
     * @param pageSize 每页条数
     * @return
     * @throws Exception
     */
    @Override
    public Paged<OrderEnterpriseBizDto> getOrderList(Map<String, Object> params, int pageNum, int pageSize) throws Exception {

        Paged<OrderEnterpriseBizDto> result = null;
        // 统计每种状态下的数据
        EnterpriseStateEnum enterpriseStateEnum = null;
        if (params.get("state") != null) {
            enterpriseStateEnum = EnterpriseStateEnum.getEnum(Integer.parseInt(params.get("state").toString()));
        }

        List<TabDto> tabList = new ArrayList<>();
        Map<String, Object> countParamMap = new HashMap<>();
        for (EnterpriseStateEnum value : EnterpriseStateEnum.values()) {
            countParamMap.put("state", value.getValue());
            Integer count = orderEnterpriseService.getCount(countParamMap);
            TabDto dto = new TabDto();
            dto.setCount(count == null ? 0 : count);
            dto.setName(value.getName());
            dto.setType(value.getValue());
            tabList.add(dto);
        }

        List<TabDto> listSort = tabList.stream().sorted(Comparator.comparing(TabDto::getType)).collect(Collectors.toList());
        Integer all = 0;
        for (TabDto tabDto : tabList) {
            all = tabDto.getCount()+all;
        }
        TabDto tabDto = new TabDto();
        tabDto.setType(null);
        tabDto.setCount(all);
        tabDto.setName("全部");
        listSort.add(0, tabDto);

        result = new Paged<>(new ArrayList<>(), 0, pageSize);
        result.setTab(listSort);

        Paged<OrderEnterpriseDto> res = orderEnterpriseService.getOrderList(params, pageNum, pageSize);
        if (res == null) {
            return result;
        } else if (res.isEmpty()) {
            return result.setTotal(res.getTotal());
        }

        List<Long> codes = new ArrayList<>();
        Map<Long, Map<Integer, Integer>> countMap = new HashMap<>();

        List<Long> firstAmountOrderCodes = new ArrayList<>();
        List<Long> payedAmountOrderCodes = new ArrayList<>();
        Map<Long, BigDecimal> firstPayMap = new HashMap<>();
        Map<Long, BigDecimal> payedMap = new HashMap<>();

        for (OrderEnterpriseDto dto : res.getList()) {
            if (dto != null && dto.getOrderCode() != null) {
                codes.add(dto.getOrderCode());
                Map<Integer, Integer> tmp = new HashMap<>();
                tmp.put(0, 0);
                tmp.put(EnterpriseCarStateEnum.LEASE.getValue(), 0);
                tmp.put(EnterpriseCarStateEnum.RETURNED.getValue(), 0);
                tmp.put(EnterpriseCarStateEnum.TRANSFERED.getValue(), 0);
                tmp.put(EnterpriseCarStateEnum.UNDELIVERY.getValue(), 0);
                countMap.put(dto.getOrderCode(), tmp);

                if (EnterpriseStateEnum.UNPAID.getValue() == dto.getState()) {
                    firstAmountOrderCodes.add(dto.getOrderCode());
                } else {
                    payedAmountOrderCodes.add(dto.getOrderCode());
                }

                firstPayMap.put(dto.getOrderCode(), new BigDecimal(0));
                payedMap.put(dto.getOrderCode(), new BigDecimal(0));
            }

        }

        List<EnterpriseCarDto> carList = enterpriseCarService.listEnterpriseCar(codes);

        for (EnterpriseCarDto carDto : carList) {
            if (carDto != null) {
                Long orderCode = carDto.getOrderCode();
                if (orderCode != null) {
                    Map<Integer, Integer> tmp = countMap.get(orderCode);
                    tmp.put(0, tmp.get(0) + 1); //总数+1;
                    Integer count = tmp.get(carDto.getState());
                    if (count != null) {
                        tmp.put(carDto.getState(), count + 1);
                    }
                    countMap.put(orderCode, tmp);
                }

                firstPayMap.put(orderCode, firstPayMap.get(orderCode).add(carDto.getPeriodsRental()));
            }
        }

        if (params.get("state") == null || enterpriseStateEnum.getValue() != EnterpriseStateEnum.UNPAID.getValue()) {
            List<EnterpriseScheduleDto> scheduleList = enterpriseScheduleService.getScheduleByOrderCodes(codes);
            if (scheduleList != null && scheduleList.size() > 0) {
                List<Integer> scheIdList = new ArrayList<>();
                Map<Integer, Long> scheIdMap = new HashMap<>();
                for (EnterpriseScheduleDto scheduleDto : scheduleList) {
                    if (scheduleDto != null) {
                        scheIdList.add(scheduleDto.getScheduleId());
                        scheIdMap.put(scheduleDto.getScheduleId(), scheduleDto.getOrderCode());
                    }
                }
                Map<Integer, EnterpriseScheduleCarCountDto> carScheMap = enterpriseScheduleCarService.getPayableMap(scheIdList);
                if (carScheMap != null) {
                    for (Map.Entry<Integer, EnterpriseScheduleCarCountDto> carSche : carScheMap.entrySet()) {
                        Long orderCode = scheIdMap.get(carSche.getKey());
                        if (carSche.getValue() != null && orderCode != null) {
                            EnterpriseScheduleCarCountDto countDto = carSche.getValue();
                            payedMap.put(orderCode, payedMap.get(orderCode).add(countDto.getAllPayable()));
                        }
                    }
                }
            }
        }

        for (OrderEnterpriseDto dto : res.getList()) {

            OrderEnterpriseBizDto bizDto = new OrderEnterpriseBizDto();
            BeanUtils.copyProperties(dto, bizDto);
            bizDto.setStateStr(EnterpriseStateEnum.getName(bizDto.getState()));
            Map<Integer, Integer> tmp = countMap.get(bizDto.getOrderCode());
            bizDto.setVehicleCount(tmp.get(0));


            if (enterpriseStateEnum == null || enterpriseStateEnum.getValue() == EnterpriseStateEnum.DELIVERY.getValue()) {
                EnterpriseStateEnum enterpriseStateEnumTmp = null;
                enterpriseStateEnumTmp = EnterpriseStateEnum.getEnum(dto.getState());
                switch (enterpriseStateEnumTmp) {
                    case DELIVERY:
                        String vehicleStateCount = tmp.get(EnterpriseCarStateEnum.LEASE.getValue())
                                + "/" + tmp.get(EnterpriseCarStateEnum.RETURNED.getValue())
                                + "/" + tmp.get(EnterpriseCarStateEnum.TRANSFERED.getValue());
                        bizDto.setVehicleStateCount(vehicleStateCount);
                        break;
                    default:
                        bizDto.setVehicleStateCount("--");
                        break;
                }
            } else if (enterpriseStateEnum.getValue() == (EnterpriseStateEnum.UNDELIVERY.getValue())) {
                bizDto.setVehicleStateCount(tmp.get(EnterpriseCarStateEnum.UNDELIVERY.getValue()) + "辆");
            }

            LocalDate localTime = bizDto.getLeaseExpire();
            if (localTime != null) {
                LocalDate addDays = bizDto.getLeaseExpire().plusDays(25);
                LocalDate minusDays = bizDto.getLeaseExpire().minusDays(25);
                LocalDate now = LocalDate.now();
                bizDto.setLeaseExpire(localTime);
                if (dto.getIsHaveSuborder()) {
                    bizDto.setSuborderState(1);
                } else {
                    if (now.isBefore(addDays) && now.isAfter(minusDays)
                            && tmp.get(EnterpriseCarStateEnum.LEASE.getValue()) != null
                            && tmp.get(EnterpriseCarStateEnum.LEASE.getValue()) > 0) {
                        bizDto.setSuborderState(0);
                    } else {
                        bizDto.setSuborderState(2);
                    }
                }
            }

            EnterpriseStateEnum enterpriseStateEnumTmp = EnterpriseStateEnum.getEnum(dto.getState());
            BigDecimal total = bizDto.getRental().add(bizDto.getDeposit());
            bizDto.setTotalAmount("总金额" + total.longValue() + "元");
            if (EnterpriseStateEnum.UNPAID.getValue() == enterpriseStateEnumTmp.getValue()) {
                BigDecimal parentDeposit = dto.getPrentOrderDeposit() == null ? new BigDecimal(0) : dto.getPrentOrderDeposit();
                bizDto.setDisplayAmount("首付" + firstPayMap.get(bizDto.getOrderCode()).add(bizDto.getDeposit()).subtract(parentDeposit).longValue() + "元");
            } else {
                bizDto.setDisplayAmount("已付" + payedMap.get(bizDto.getOrderCode()).add(bizDto.getDeposit()).longValue() + "元");
            }
            result.getList().add(bizDto);
        }
        result.setTotal(res.getTotal());
        return result;
    }

    /**
     * 查询租赁车辆列表
     *
     * @param params
     * @param pageNum  页数
     * @param pageSize 每页条数
     * @return
     * @throws Exception
     */
    @Override
    public Paged<OrderEnterpriseCarBizDto> getOrderEnterpriseCarList(Map<String, Object> params, int pageNum, int pageSize) throws Exception {

        Paged<OrderEnterpriseCarBizDto> result = null;
        // 统计每种状态下的数据量
        EnterpriseCarStateEnum enterpriseCarStateEnum = null;
        if (params.get("state") != null) {
            enterpriseCarStateEnum = EnterpriseCarStateEnum.getEnum(Integer.parseInt(params.get("state").toString()));
        }

        result = new Paged<OrderEnterpriseCarBizDto>(new ArrayList<>(), 0, pageSize);

        List<TabDto> tabList = new ArrayList<>();
        Map<String, Object> countParamMap = new HashMap<>();
        for (EnterpriseCarStateEnum value : EnterpriseCarStateEnum.values()) {
            countParamMap.put("state", value.getValue());
            Integer count = enterpriseCarService.getCount(countParamMap);
            TabDto dto = new TabDto();
            dto.setCount(count == null ? 0 : count);
            dto.setName(value.getName());
            dto.setType(value.getValue());
            tabList.add(dto);
        }
        List<TabDto> listSort = tabList.stream().sorted(Comparator.comparing(TabDto::getType)).collect(Collectors.toList());
        Integer all = 0;
        for (TabDto tabDto : tabList) {
            all = tabDto.getCount()+all;
        }

        TabDto tabDto = new TabDto();
        tabDto.setType(null);
        tabDto.setCount(all);
        tabDto.setName("全部");
        listSort.add(0, tabDto);
        result.setTab(listSort);


        List<Long> orderCodes = new ArrayList<>();

        if (params.get("enterpriseId") != null) {
            Integer enterpriseId = ObjectCastUtil.castInteger(params.get("enterpriseId"));
            List<OrderEnterpriseDto> orderEnterpriselist = orderEnterpriseService.getByEnterpriseId(enterpriseId);
            if (orderEnterpriselist == null || orderEnterpriselist.size() <= 0) {
                return result;
            }
            Set<Long> orderCodeSet = new HashSet<>();
            for (OrderEnterpriseDto orderEnterpriseDto : orderEnterpriselist) {
                if (orderEnterpriseDto != null && orderEnterpriseDto.getOrderCode() != null) {
                    orderCodeSet.add(orderEnterpriseDto.getOrderCode());
                }
            }
            orderCodes.addAll(orderCodeSet);
        }
        if (enterpriseCarStateEnum != null) {
            switch (enterpriseCarStateEnum) {
                case UNPAID:
                case RELETED:
                    if (params.get("leaseInceptionStart") != null
                            || params.get("leaseInceptionEnd") != null
                            || params.get("leaseExpireStart") != null
                            || params.get("leaseExpireEnd") != null) {
                        // 起租日开始时间-LocalDateTime
                        params.put("leaseInceptionStart", ObjectCastUtil.castLocalDateTimeStart(params.get("leaseInceptionStart")));
                        // 起租日结束时间-LocalDateTime
                        params.put("leaseInceptionEnd", ObjectCastUtil.castLocalDateTimeEnd(params.get("leaseInceptionEnd")));
                        // 租赁截止日开始时间-LocalDateTime
                        params.put("leaseExpireStart", ObjectCastUtil.castLocalDateTimeStart(params.get("leaseExpireStart")));
                        // 租赁截止日结束时间-LocalDateTime
                        params.put("leaseExpireEnd", ObjectCastUtil.castLocalDateTimeEnd(params.get("leaseExpireEnd")));
                        Set<Long> orderCodeSet = orderEnterpriseService.getByDate(params);
                        if (orderCodeSet == null || orderCodeSet.size() <= 0) {
                            return result;
                        }
                        if (orderCodes.size() > 0) {
                            List<Long> intersection = orderCodes.stream().filter(item -> orderCodeSet.contains(item)).collect(toList());
                            if (intersection == null || intersection.size() <= 0) {
                                return result;
                            }
                            orderCodes = intersection;
                        } else {
                            orderCodes.addAll(orderCodeSet);
                        }

                    }

                    break;
                case RETURNED:
                    if (params.get("leaseInceptionStart") != null
                            || params.get("leaseInceptionEnd") != null) {
                        // 起租日开始时间-LocalDateTime
                        params.put("leaseInceptionStart", ObjectCastUtil.castLocalDateTimeStart(params.get("leaseInceptionStart")));
                        // 起租日结束时间-LocalDateTime
                        params.put("leaseInceptionEnd", ObjectCastUtil.castLocalDateTimeEnd(params.get("leaseInceptionEnd")));
                        Set<Long> orderCodeSet = orderEnterpriseService.getByDate(params);
                        if (orderCodeSet == null || orderCodeSet.size() <= 0) {
                            return result;
                        }

                        if (orderCodes.size() > 0) {
                            List<Long> intersection = orderCodes.stream().filter(item -> orderCodeSet.contains(item)).collect(toList());
                            if (intersection == null || intersection.size() <= 0) {
                                return result;
                            }
                            orderCodes = intersection;
                        } else {
                            orderCodes.addAll(orderCodeSet);
                        }
                    }
                    //还车(退租)
                    if (params.get("returnedTimeStart") != null || params.get("returnedTimeEnd") != null) {
                        Integer enterpriseId = ObjectCastUtil.castInteger(params.get("enterpriseId"));
                        List<EnterpriseCarHandoverDto> returnedlist = enterpriseCarHandoverService.getByReturnedTime(params);
                        if (returnedlist == null || returnedlist.size() <= 0) {
                            return result;
                        }
                        Set<Long> orderCodeSet = new HashSet<>();
                        for (EnterpriseCarHandoverDto dto : returnedlist) {
                            if (dto != null && dto.getOrderCode() != null) {
                                orderCodeSet.add(dto.getOrderCode());
                            }
                        }
                        if (orderCodes.size() > 0) {
                            List<Long> intersection = orderCodes.stream().filter(item -> orderCodeSet.contains(item)).collect(toList());
                            if (intersection == null || intersection.size() <= 0) {
                                return result;
                            }
                            orderCodes = intersection;
                        } else {
                            orderCodes.addAll(orderCodeSet);
                        }
                    }
                case TRANSFERED: //过户
                    if (params.get("leaseInceptionStart") != null
                            || params.get("leaseInceptionEnd") != null) {
                        // 起租日开始时间-LocalDateTime
                        params.put("leaseInceptionStart", ObjectCastUtil.castLocalDateTimeStart(params.get("leaseInceptionStart")));
                        // 起租日结束时间-LocalDateTime
                        params.put("leaseInceptionEnd", ObjectCastUtil.castLocalDateTimeEnd(params.get("leaseInceptionEnd")));
                        Set<Long> orderCodeSet = orderEnterpriseService.getByDate(params);
                        if (orderCodeSet == null || orderCodeSet.size() <= 0) {
                            return result;
                        }

                        if (orderCodes.size() > 0) {
                            List<Long> intersection = orderCodes.stream().filter(item -> orderCodeSet.contains(item)).collect(toList());
                            if (intersection == null || intersection.size() <= 0) {
                                return result;
                            }
                            orderCodes = intersection;
                        } else {
                            orderCodes.addAll(orderCodeSet);
                        }
                    }

                    if (params.get("transferTimeStart") != null || params.get("transferTimeEnd") != null) {
                        Integer enterpriseId = ObjectCastUtil.castInteger(params.get("enterpriseId"));

                        List<EnterpriseCarTransferDto> transferlist = enterpriseCarTransferService.getBytransferTime(params);
                        if (transferlist == null || transferlist.size() <= 0) {
                            return result;
                        }
                        Set<Long> orderCodeSet = new HashSet<>();
                        for (EnterpriseCarTransferDto dto : transferlist) {
                            if (dto != null && dto.getOrderCode() != null) {
                                orderCodeSet.add(dto.getOrderCode());
                            }
                        }
                        if (orderCodes.size() > 0) {
                            List<Long> intersection = orderCodes.stream().filter(item -> orderCodeSet.contains(item)).collect(toList());
                            if (intersection == null || intersection.size() <= 0) {
                                return result;
                            }
                            orderCodes = intersection;
                        } else {
                            orderCodes.addAll(orderCodeSet);
                        }
                    }

                    break;
                case UNDELIVERY:
                case UNHIRE:
                case LEASE:
                default:
                    break;
            }
        } else {
            if (params.get("leaseInceptionStart") != null
                    || params.get("leaseInceptionEnd") != null
                    || params.get("leaseExpireStart") != null
                    || params.get("leaseExpireEnd") != null) {
                // 起租日开始时间-LocalDateTime
                params.put("leaseInceptionStart", ObjectCastUtil.castLocalDateTimeStart(params.get("leaseInceptionStart")));
                // 起租日结束时间-LocalDateTime
                params.put("leaseInceptionEnd", ObjectCastUtil.castLocalDateTimeEnd(params.get("leaseInceptionEnd")));
                // 租赁截止日开始时间-LocalDateTime
                params.put("leaseExpireStart", ObjectCastUtil.castLocalDateTimeStart(params.get("leaseExpireStart")));
                // 租赁截止日结束时间-LocalDateTime
                params.put("leaseExpireEnd", ObjectCastUtil.castLocalDateTimeEnd(params.get("leaseExpireEnd")));
                Set<Long> orderCodeSet = orderEnterpriseService.getByDate(params);
                if (orderCodeSet == null || orderCodeSet.size() <= 0) {
                    return result;
                }
                if (orderCodes.size() > 0) {
                    List<Long> intersection = orderCodes.stream().filter(item -> orderCodeSet.contains(item)).collect(toList());
                    if (intersection == null || intersection.size() <= 0) {
                        return result;
                    }
                    orderCodes = intersection;
                } else {
                    orderCodes.addAll(orderCodeSet);
                }

            }
        }

        if (orderCodes != null && orderCodes.size() > 0) {
            params.put("orderCodes", orderCodes);
        }

        //查询租赁车辆表
        Paged<EnterpriseCarDto> enterpriseCarDtoPage = enterpriseCarService.getOrderCarList(params, pageNum, pageSize);
        if (enterpriseCarDtoPage == null) {
            return result;
        } else if (enterpriseCarDtoPage.isEmpty()) {
            return result.setTotal(enterpriseCarDtoPage.getTotal());
        }

        List<Long> enterpriseOrderCodes = new ArrayList<>();
        List<EnterpriseCarHandoverDto> handoverDtoList = new ArrayList<>();
        List<EnterpriseCarTransferDto> transferedDtoList = new ArrayList<>();

        for (EnterpriseCarDto dto : enterpriseCarDtoPage.getList()) {
            if (dto != null && dto.getOrderCode() != null) {
                enterpriseOrderCodes.add(dto.getOrderCode());
                if (!StringUtils.isEmpty(dto.getCarId())) {
                    EnterpriseCarHandoverDto enterpriseCarHandoverDto = new EnterpriseCarHandoverDto();
                    enterpriseCarHandoverDto.setCarId(dto.getCarId());
                    enterpriseCarHandoverDto.setOrderCode(dto.getOrderCode());
                    handoverDtoList.add(enterpriseCarHandoverDto);

                    EnterpriseCarTransferDto transferedDto = new EnterpriseCarTransferDto();
                    transferedDto.setCarId(dto.getCarId());
                    transferedDto.setOrderCode(dto.getOrderCode());
                    transferedDtoList.add(transferedDto);
                }
            }
        }

        //获取订单信息
        Map<Long, OrderEnterpriseDto> orderMap = orderEnterpriseService.getEnterpriseMap(enterpriseOrderCodes);

        Map<Long, Long> parentOrderCodeMap = null;
        Map<String, EnterpriseCarHandoverDto> handoverDeliveryDtoMap = null;
        Map<String, EnterpriseCarHandoverDto> handoverReturnDtoMap = null;
        Map<Integer, EnterpriseCarTransferDto> transferedDtoMap = null;
        if (enterpriseCarStateEnum != null) {
            switch (enterpriseCarStateEnum) {
                case UNHIRE:
                    handoverDeliveryDtoMap = enterpriseCarHandoverService.getByDto(handoverDtoList, EnterpriseCarHandoverTypeEnum.DELIVERY);
                    break;
                case RETURNED:
                    handoverReturnDtoMap = enterpriseCarHandoverService.getByDto(handoverDtoList, EnterpriseCarHandoverTypeEnum.RETURN);
                    break;
                case TRANSFERED:
                    transferedDtoMap = enterpriseCarTransferService.getByDto(transferedDtoList);
                    break;
                case RELETED:
                    parentOrderCodeMap = orderEnterpriseService.getOrderCodeByParentOrderCodes(enterpriseOrderCodes);
                    break;
                case LEASE:
                case UNPAID:
                case UNDELIVERY:
                default:
                    break;
            }
        } else {
            handoverDeliveryDtoMap = enterpriseCarHandoverService.getByDto(handoverDtoList, EnterpriseCarHandoverTypeEnum.DELIVERY);
            handoverReturnDtoMap = enterpriseCarHandoverService.getByDto(handoverDtoList, EnterpriseCarHandoverTypeEnum.RETURN);
            transferedDtoMap = enterpriseCarTransferService.getByDto(transferedDtoList);
            parentOrderCodeMap = orderEnterpriseService.getOrderCodeByParentOrderCodes(enterpriseOrderCodes);
        }


        for (EnterpriseCarDto dto : enterpriseCarDtoPage.getList()) {
            OrderEnterpriseCarBizDto bizDto = new OrderEnterpriseCarBizDto();
            BeanUtils.copyProperties(dto, bizDto);
            if (bizDto == null && bizDto.getState() == null) {
                continue;
            }
            EnterpriseCarStateEnum tmpState = EnterpriseCarStateEnum.getEnum(bizDto.getState());
            if (bizDto != null && EnterpriseCarStateEnum.getEnum(bizDto.getState()) != null) {
                String stateStr = EnterpriseCarStateEnum.getEnum(bizDto.getState()).getName();
                bizDto.setStateStr(stateStr);
            }

            Long orderCode = dto.getOrderCode();
            if (orderMap != null && orderMap.size() > 0) {
                OrderEnterpriseDto orderDto = orderMap.get(orderCode);
                if (orderDto != null) {
                    bizDto.setEnterpriseName(orderDto.getEnterpriseName());
                    bizDto.setLeaseExpire(orderDto.getLeaseExpire());
                    bizDto.setLeaseInception(orderDto.getLeaseInception());
                }
            }

            if (handoverDeliveryDtoMap != null && handoverDeliveryDtoMap.size() > 0) {
                EnterpriseCarHandoverDto handoverDto = handoverDeliveryDtoMap.get(dto.getOrderCode() + "_" + dto.getCarId());
                if (handoverDto != null && tmpState.getValue() == (EnterpriseCarStateEnum.UNHIRE.getValue())) {
                    bizDto.setEnterpriseReceiver(handoverDto.getEnterpriseReceiver());
                    bizDto.setEnterpriseReceiverIdcard(handoverDto.getEnterpriseReceiverIdcard());
                    bizDto.setHandoverTime(handoverDto.getHandoverTime());
                }
            }

            if (handoverReturnDtoMap != null && handoverReturnDtoMap.size() > 0) {
                EnterpriseCarHandoverDto handoverDto = handoverReturnDtoMap.get(dto.getOrderCode() + "_" + dto.getCarId());
                if (handoverDto != null && tmpState.getValue() == (EnterpriseCarStateEnum.RETURNED.getValue())) {
                    bizDto.setEnterpriseReceiver(handoverDto.getEnterpriseReceiver());
                    bizDto.setEnterpriseReceiverIdcard(handoverDto.getEnterpriseReceiverIdcard());
                    bizDto.setHandoverTime(handoverDto.getHandoverTime());
                    bizDto.setCarHandoverId(handoverDto.getId());
                }
            }

            if (transferedDtoMap != null && transferedDtoMap.size() > 0) {
                EnterpriseCarTransferDto transferedDto = transferedDtoMap.get(dto.getCarId());
                if (transferedDto != null) {
                    bizDto.setTransferTime(transferedDto.getGmtCreate());
                }

            }
            if (parentOrderCodeMap != null && parentOrderCodeMap.size() > 0) {
                bizDto.setChildOrderCode(parentOrderCodeMap.get(orderCode));
            }
            result.getList().add(bizDto);
        }

        result.setTotal(enterpriseCarDtoPage.getTotal());
        return result;

    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public Boolean leaseConfirm(OrderEnterpriseLeaseConfirmBizDto modifyBizDto) {

        logger.info("[起租确认]入参：" + modifyBizDto);

        if (modifyBizDto == null || modifyBizDto.getOrderCode() == null) {
            logger.error("[leaseConfirm]起租确认失败，参数错误：" + modifyBizDto);
            return false;
        }

        Long orderCode = modifyBizDto.getOrderCode();

        OrderEnterpriseDto order = orderEnterpriseService.getEnterprise(orderCode);
        if (order == null) {
            logger.error("[leaseConfirm]起租确认失败，订单(" + orderCode + ")不存在");
            return false;
        } else if (EnterpriseStateEnum.UNHIRE.getValue() != order.getState()) {
            logger.error("[leaseConfirm]起租确认失败，订单(" + orderCode + ")" +
                    "状态(" + order.getState() + ")不是待起租状态");
            return false;
        }

        // 修改订单状态
        Integer modifyLeaseConfirm = orderEnterpriseService.modifyLeaseConfirm(orderCode, EnterpriseStateEnum.UNHIRE.getValue(),
                EnterpriseStateEnum.DELIVERY.getValue(), modifyBizDto.getLeaseInception(), modifyBizDto.getLeaseInception().plusMonths(order.getTenancy()));
        if (modifyLeaseConfirm <= 0) {
            logger.error("[modifyLeaseConfirm]起租确认失败修改企业订单(" + orderCode + ")失败");
            throw new BizException(OrderExceptionCodeEnum.ERROR.getCode(), "修改订单状态失败");
        }
        order.setLeaseInception(modifyBizDto.getLeaseInception());
        order.setLeaseExpire(modifyBizDto.getLeaseInception().plusMonths(order.getTenancy()));
        // 修改订单车辆状态
        if (!enterpriseCarService.modifyState(orderCode, EnterpriseCarStateEnum.UNHIRE, EnterpriseCarStateEnum.LEASE)) {
            logger.error("[leaseConfirm]起租确认失败修改企业订单(" + orderCode + ")车辆状态失败");
            throw new BizException(OrderExceptionCodeEnum.ERROR.getCode(), "订单修改车辆状态失败");
        }

        List<EnterpriseCarDto> carList = enterpriseCarService.getEnterpriseCar(orderCode);
        createSchedule(order, carList);
        // 新增订单流转信息
        enterpriseStateFlowService.create(Convert.toEnterpriseStateFlowCreateDto(modifyBizDto, EnterpriseStateEnum.DELIVERY));

        return true;
    }

    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public void createSchedule(OrderEnterpriseDto order, List<EnterpriseCarDto> carList) {
        for (int i = 2; i <= order.getTenancy() / order.getRepaymentPeriod(); i++) {

            EnterpriseScheduleCreateDto scheduleDto = new EnterpriseScheduleCreateDto();
            scheduleDto.setOrderCode(order.getOrderCode());
            scheduleDto.setEnterpriseId(order.getEnterpriseId());
            scheduleDto.setPeriods(i);
            scheduleDto.setTotalPeriods(order.getTenancy() / order.getRepaymentPeriod());
            scheduleDto.setArrivalAmount(null);

            LocalDate date = order.getLeaseInception();
            if (order.getLeaseInception().getDayOfMonth() >= 29) {
                date = date.plusMonths(1);
                date = date.withDayOfMonth(1);
            }
            date = date.plusMonths((i - 1) * order.getRepaymentPeriod());
            scheduleDto.setPayableDate(date);
            scheduleDto.setPayTime(null);
            scheduleDto.setState(EnterpriseScheduleStateEnum.NO);
            Integer scheduleId = enterpriseScheduleService.create(scheduleDto);
            if (scheduleId == null) {
                logger.error("[createSchedule]起租确认,新增订单(" + order.getOrderCode() + ")排期失败");
                throw new BizException(OrderExceptionCodeEnum.ERROR.getCode(), "起租确认,新增订单排期失败");
            }

            List<EnterpriseScheduleCarCreateDto> createDtos = new ArrayList<>();
            for (EnterpriseCarDto car : carList) {
                EnterpriseScheduleCarCreateDto dto = new EnterpriseScheduleCarCreateDto();
                dto.setCarId(car.getCarId());
                dto.setPayable(car.getPeriodsRental());
                dto.setScheduleId(scheduleId);
                dto.setState(EnterpriseScheduleStateEnum.NO);
                createDtos.add(dto);
            }
            if (!enterpriseScheduleCarService.createBatch(createDtos)) {
                logger.error("[createSchedule]起租确认,新增订单(" + order.getOrderCode() + ")车辆排期失败");
                throw new BizException(OrderExceptionCodeEnum.ERROR.getCode(), "起租确认,新增车辆排期失败");
            }
        }
    }


    /**
     * 查询到期订单（如有续订，包含续订信息）
     *
     * @param leaseExpire 到期日
     * @return
     */
    public List<EnterpriseExpireBizDto> getExpire(LocalDate leaseExpire) {
        List<EnterpriseExpireBizDto> result = null;
        // 查询到期订单
        List<OrderEnterpriseDto> expireEnterpriseDtos = orderEnterpriseService.getExpire(leaseExpire);
        if (expireEnterpriseDtos == null || expireEnterpriseDtos.isEmpty()) {
            // 不存在到期订单
            logger.info(DateUtil.formatDate(leaseExpire) + "不存在到期订单");
            return result;
        }
        result = new ArrayList<>();
        // 存在，循环查询该订单租赁中的车辆
        for (OrderEnterpriseDto expireEnterpriseDto : expireEnterpriseDtos) {
            List<EnterpriseCarDto> enterpriseCars = enterpriseCarService.
                    getEnterpriseCar(expireEnterpriseDto.getOrderCode(), EnterpriseCarStateEnum.LEASE);
            if (enterpriseCars == null) {
                continue;
            }
            result.add(Convert.toEnterpriseExpireBizDto(expireEnterpriseDto, enterpriseCars));
        }

        return result.isEmpty() ? null : result;
    }

    /**
     * 获取续订单信息
     *
     * @param leaseInception 起租日
     * @return
     */
    @Override
    public List<EnterpriseRenewBizDto> getRenewLease(LocalDate leaseInception) {
        List<EnterpriseRenewBizDto> result = null;
        // 查询到期订单
        List<OrderEnterpriseDto> enterpriseDtos = orderEnterpriseService.getRenewLease(leaseInception);
        if (enterpriseDtos == null || enterpriseDtos.isEmpty()) {
            // 不存在待起租的续订订单
            logger.info(DateUtil.formatDate(leaseInception) + "不存在待起租续订订单");
            return result;
        }
        result = new ArrayList<>();
        // 存在，查询车辆信息
        for (OrderEnterpriseDto enterpriseDto : enterpriseDtos) {
            List<EnterpriseCarDto> enterpriseCars = enterpriseCarService.
                    getEnterpriseCar(enterpriseDto.getOrderCode(), EnterpriseCarStateEnum.UNHIRE);
            if (enterpriseCars == null) {
                continue;
            }
            result.add(Convert.toEnterpriseRenewBizDto(enterpriseDto, enterpriseCars));
        }

        return result.isEmpty() ? null : result;
    }

    /**
     * 续订订单起租修改
     *
     * @param modifyBizDto 修改信息
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public boolean modifyRenewLease(EnterpriseRenewLeaseModifyBizDto modifyBizDto) {
        // 查询订单信息
        OrderEnterpriseDto enterpriseDto = orderEnterpriseService.getEnterprise(modifyBizDto.getOrderCode());
        if (enterpriseDto == null) {
            logger.error("[modifyRenewLease]续订订单起租修改失败，订单({})不存在", modifyBizDto.getOrderCode());
            return false;
        }
        // 修改订单状态
        if (!orderEnterpriseService.modifyState(modifyBizDto.getOrderCode(),
                EnterpriseStateEnum.UNHIRE, EnterpriseStateEnum.DELIVERY)) {
            logger.error("[modifyRenewLease]续订订单起租修改失败，订单({})状态({})异常",
                    modifyBizDto.getOrderCode(), enterpriseDto.getState());
            return false;
        }
        // 新增流转
        enterpriseStateFlowService.create(Convert.toEnterpriseStateFlowCreateDto(modifyBizDto));

        Map<Integer, EnterpriseCarDto> parentEnterpriseCarMap = null;
        // 查询主订单再租车辆信息
        List<EnterpriseCarDto> parentEnterpriseCars = enterpriseCarService.
                getEnterpriseCar(enterpriseDto.getPrentOrderCode(), EnterpriseCarStateEnum.LEASE);
        if (parentEnterpriseCars != null && !parentEnterpriseCars.isEmpty()) {
            parentEnterpriseCarMap = parentEnterpriseCars.stream()
                    .collect(Collectors.toMap(EnterpriseCarDto::getCarId, carDto -> carDto));
        }

        for (EnterpriseRenewCarLeaseModifyBizDto carModifyBizDto : modifyBizDto.getCarList()) {
            // 是否存在主订单车辆
            EnterpriseCarDto parentCarDto = null;
            if (parentEnterpriseCarMap != null
                    && (parentCarDto = parentEnterpriseCarMap.get(carModifyBizDto.getCarId())) != null) {
                // 存在，修改主订单车辆
                EnterpriseCarModifyDto parentCarModifyDto = new EnterpriseCarModifyDto();
                BeanUtils.copyProperties(parentCarDto, parentCarModifyDto);
                // 父订单车辆结束里程 = 子订单车辆开始里程
                parentCarModifyDto.setEndMileage(carModifyBizDto.getStartMileage());

                enterpriseCarService.modifyExpire(parentCarModifyDto);
            }
            // 修改续租订单车辆
            EnterpriseCarModifyDto modifyDto = new EnterpriseCarModifyDto();
            BeanUtils.copyProperties(carModifyBizDto, modifyDto);
            enterpriseCarService.modifyLease(modifyDto);
        }
        // 添加排期信息
        createSchedule(enterpriseDto, enterpriseCarService.getEnterpriseCar(enterpriseDto.getOrderCode()));

        return true;
    }

    /**
     * 根据根据车辆ID获取企业订单
     *
     * @param carId
     * @return
     */
    @Override
    public List<OrderEnterpriseBizDto> getListByCarId(Integer carId) {
        List<OrderEnterpriseBizDto> res = null;
        List<EnterpriseCarDto> carList = enterpriseCarService.getOrderCarListByCarId(carId);
        if (carList != null && carList.size() > 0) {
            List<Long> orderCodeList = new ArrayList<>();
            List<EnterpriseCarHandoverDto> handoverDtoList = new ArrayList<>();
            for (EnterpriseCarDto carDto : carList) {
                if (carDto != null && carDto.getOrderCode() != null) {
                    orderCodeList.add(carDto.getOrderCode());
                    if (carDto.getCarId() != null) {
                        EnterpriseCarHandoverDto handoverDto = new EnterpriseCarHandoverDto();
                        handoverDto.setOrderCode(carDto.getOrderCode());
                        handoverDto.setCarId(carDto.getCarId());
                        handoverDtoList.add(handoverDto);
                    }
                }
            }
            if (orderCodeList.size() > 0) {
                List<OrderEnterpriseDto> orderList = orderEnterpriseService.getEnterpriseList(orderCodeList);
                Map<String, EnterpriseCarHandoverDto> handoverMap = enterpriseCarHandoverService.getByDto(handoverDtoList, EnterpriseCarHandoverTypeEnum.DELIVERY);

                if (orderList != null && orderList.size() > 0) {
                    res = new ArrayList<>();
                    for (OrderEnterpriseDto dto : orderList) {
                        if (dto != null) {
                            OrderEnterpriseBizDto bizDto = new OrderEnterpriseBizDto();
                            BeanUtils.copyProperties(dto, bizDto);
                            String key = dto.getOrderCode() + "_" + carId;
                            EnterpriseCarHandoverDto handover = handoverMap.get(dto.getOrderCode() + "_" + carId);
                            if (handover != null) {
                                bizDto.setHandoverTime(handover.getHandoverTime());
                            }
                            res.add(bizDto);
                        }
                    }
                }
            }
        }
        return res;
    }

    /**
     * 获取订单流转信息
     *
     * @param orderCode 订单号
     * @return
     * @throws Exception
     */
    @Override
    public List<OrderTradeFlowBizDto> getOrderFlow(Long orderCode) throws Exception {
        List<OrderTradeFlowBizDto> result = Arrays.asList(
                new OrderTradeFlowBizDto(OrderTradeFlowStatusEnum.WAIT, "创建订单"),
                new OrderTradeFlowBizDto(OrderTradeFlowStatusEnum.WAIT, "付款"),
                new OrderTradeFlowBizDto(OrderTradeFlowStatusEnum.WAIT, "起租"),
                new OrderTradeFlowBizDto(OrderTradeFlowStatusEnum.WAIT, "到期"));

        // 根据订单号查询订单信息
        OrderEnterpriseDto enterpriseDto = orderEnterpriseService.getEnterprise(orderCode);
        if (enterpriseDto == null) {
            logger.error("订单({})不存在", orderCode);
            throw new BizException(OrderExceptionCodeEnum.NOT_EXIST.getCode(), "订单不存在");
        }
        // 查询订单流转信息
        List<EnterpriseStateFlowDto> flowList = enterpriseStateFlowService.getListByOrderCode(orderCode);
        if (flowList == null || flowList.isEmpty()) {
            return result;
        }
        Map<Integer, EnterpriseStateFlowDto> flowMap = flowList.stream()
                .collect(Collectors.toMap(EnterpriseStateFlowDto::getState, dto -> dto));


        // 判断订单状态
        if (enterpriseDto.getState() == EnterpriseStateEnum.UNPAID.getValue()) {
            // 待付款-（创建订单）
            flowAssign(result.get(0), flowMap.get(EnterpriseStateEnum.UNPAID.getValue()),
                    OrderTradeFlowStatusEnum.CURRENT);
        } else if (enterpriseDto.getState() == EnterpriseStateEnum.UNDELIVERY.getValue()
                || enterpriseDto.getState() == EnterpriseStateEnum.UNHIRE.getValue()) {
            // 待交车/待起租-（付款）
            flowAssign(result.get(0), flowMap.get(EnterpriseStateEnum.UNPAID.getValue()),
                    OrderTradeFlowStatusEnum.COMPLETED);
            flowAssign(result.get(1),
                    flowMap.get(enterpriseDto.getPrentOrderCode() == null ?
                            EnterpriseStateEnum.UNPAID.getValue() : EnterpriseStateEnum.UNHIRE.getValue()),
                    OrderTradeFlowStatusEnum.CURRENT);

        } else if (enterpriseDto.getState() == EnterpriseStateEnum.DELIVERY.getValue()) {
            // 已交车-（起租）/（到期）
            flowAssign(result.get(0), flowMap.get(EnterpriseStateEnum.UNPAID.getValue()),
                    OrderTradeFlowStatusEnum.COMPLETED);
            flowAssign(result.get(1),
                    flowMap.get(enterpriseDto.getPrentOrderCode() == null ?
                            EnterpriseStateEnum.UNPAID.getValue() : EnterpriseStateEnum.UNHIRE.getValue()),
                    OrderTradeFlowStatusEnum.COMPLETED);
            flowAssign(result.get(2), flowMap.get(enterpriseDto.getState()),
                    OrderTradeFlowStatusEnum.CURRENT);
            if (enterpriseDto.getLeaseExpire().isBefore(LocalDate.now())) {
                // 已过订单截止日
                result.get(2).setOrderTradeFlowStatus(OrderTradeFlowStatusEnum.COMPLETED);
                result.get(3).setOrderTradeFlowStatus(OrderTradeFlowStatusEnum.CURRENT);
                result.get(3).setExecutionTime(DateUtil.getDayEnd(enterpriseDto.getLeaseExpire()));
            }
        }
        return result;
    }

    private OrderTradeFlowBizDto flowAssign(OrderTradeFlowBizDto tradeFlowBizDto, EnterpriseStateFlowDto flowDto,
                                            OrderTradeFlowStatusEnum tradeFlowStatusEnum) {
        tradeFlowBizDto.setOrderTradeFlowStatus(tradeFlowStatusEnum);
        tradeFlowBizDto.setExecutionTime(flowDto == null ? null : flowDto.getModifiedTime());
        return tradeFlowBizDto;
    }

}
